﻿using System.NETool;

namespace NETool.Test
{
    [TestClass]
    public sealed class ArrayExTests
    {
        [TestMethod]
        public void Handle_ShouldReturnCorrectPointer()
        {
            byte[] array = { 1, 2, 3, 4 };
            IntPtr ptr = array.Handle();
            Assert.AreNotEqual(IntPtr.Zero, ptr);
        }

        [TestMethod]
        public void Disorder_ShouldShuffleArray()
        {
            int[] array = { 1, 2, 3, 4, 5 };
            array.Disorder();
            Assert.AreEqual(5, array.Length);
            Assert.IsTrue(array.Contains(1));
            Assert.IsTrue(array.Contains(2));
            Assert.IsTrue(array.Contains(3));
            Assert.IsTrue(array.Contains(4));
            Assert.IsTrue(array.Contains(5));
        }

        [TestMethod]
        public void MedianNum_ShouldReturnCorrectMedian()
        {
            int[] array = { 1, 3, 2, 5, 4 };
            int median = array.MedianNum();
            Assert.AreEqual(3, median);
        }

        [TestMethod]
        public void ToHexString_ShouldReturnCorrectHexString()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hexString = array.ToHexString();
            Assert.AreEqual("01020304", hexString);
        }

        [TestMethod]
        public void ToHexByteArray_ShouldReturnCorrectByteArray()
        {
            string hexString = "01020304";
            byte[] byteArray = hexString.ToHexByteArray();
            CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4 }, byteArray);
        }

        [TestMethod]
        public void HexPrint_ShouldNotThrowException()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            array.HexPrint("Test");
        }

        [TestMethod]
        public void HexPrint_WithOffsetAndCount_ShouldNotThrowException()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            array.HexPrint(1, 2, "Test");
        }

        [TestMethod]
        public void AsBytes_ShouldReturnCorrectSpan()
        {
            int[] array = [1, 2, 3, 4];
            Span<byte> span = array.AsBytes();
            Assert.AreEqual(array.Length * sizeof(int), span.Length);
        }

        [TestMethod]
        public void Cast_ShouldReturnCorrectSpan()
        {
            int[] array = { 1, 2, 3, 4 };
            Span<short> span = array.Cast<int, short>();
            Assert.AreEqual(array.Length * sizeof(int) / sizeof(short), span.Length);
        }

        [TestMethod]
        public void MD5String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.MD5();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA1String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA1();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA256String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA256();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA384String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA384();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA512String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA512();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA3_256String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA3_256();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA3_384String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA3_384();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void SHA3_512String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.SHA3_512();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void PBKDF2String_ShouldReturnCorrectHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.PBKDF2();
            Assert.IsNotNull(hash);
        }

        [TestMethod]
        public void PBKDF2Verify_ShouldReturnTrueForValidHash()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            string hash = array.PBKDF2();
            bool isValid = array.PBKDF2Verify(hash);
            Assert.IsTrue(isValid);
        }

        [TestMethod]
        public void AesEncrypt_ShouldReturnEncryptedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] encrypted = array.AesEncrypt("key", "iv");
            Assert.IsNotNull(encrypted);
        }

        [TestMethod]
        public void AesDecrypt_ShouldReturnDecryptedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] encrypted = array.AesEncrypt("key", "iv");
            byte[] decrypted = encrypted.AesDecrypt("key", "iv");
            CollectionAssert.AreEqual(array, decrypted);
        }

        [TestMethod]
        public void DesEncrypt_ShouldReturnEncryptedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] encrypted = array.DesEncrypt("key", "iv");
            Assert.IsNotNull(encrypted);
        }

        [TestMethod]
        public void DesDecrypt_ShouldReturnDecryptedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] encrypted = array.DesEncrypt("key", "iv");
            byte[] decrypted = encrypted.DesDecrypt("key", "iv");
            CollectionAssert.AreEqual(array, decrypted);
        }

        [TestMethod]
        public void ToMemoryStream_ShouldReturnMemoryStream()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            var stream = array.ToMemoryStream();
            Assert.IsNotNull(stream);
        }

        [TestMethod]
        public void Resize_ShouldReturnResizedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] resized = array.Resize(6);
            Assert.AreEqual(6, resized.Length);
        }

        [TestMethod]
        public void Append_ShouldReturnAppendedArray()
        {
            byte[] array1 = { 0x1, 0x2 };
            byte[] array2 = { 0x3, 0x4 };
            byte[] appended = array1.Append(array2);
            CollectionAssert.AreEqual(new byte[] { 0x1, 0x2, 0x3, 0x4 }, appended);
        }

        [TestMethod]
        public void GZipCompress_ShouldReturnCompressedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] compressed = array.GZipCompress();
            Assert.IsNotNull(compressed);
        }

        [TestMethod]
        public void GZipDecompress_ShouldReturnDecompressedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] compressed = array.GZipCompress();
            byte[] decompressed = compressed.GZipDecompress();
            CollectionAssert.AreEqual(array, decompressed);
        }

        [TestMethod]
        public void ZipCompress_ShouldReturnCompressedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] compressed = array.ZipCompress();
            Assert.IsNotNull(compressed);
        }

        [TestMethod]
        public void ZipDecompress_ShouldReturnDecompressedArray()
        {
            byte[] array = { 0x1, 0x2, 0x3, 0x4 };
            byte[] compressed = array.ZipCompress();
            byte[] decompressed = compressed.ZipDecompress();
            CollectionAssert.AreEqual(array, decompressed);
        }
    }
}
